#include "QuadTree.h"

QuadTree::QuadTree()
{
	root = NULL;
}
QuadTree::QuadTree(int pos_x, int pos_y, int size, int level)
{
	this->max_level = level;
	root = new QNode(pos_x, pos_y, size, 0, 0);
}

QuadTree::~QuadTree()
{
	if (root != NULL)
	{
		delete root;
	}
}

void QuadTree::clip(RECT camara_rect, QNode *p_qnode, list<Object*>* p_obj_list)
{
	bool is_clip = false;

	/*Box b1(camara_rect.left, camara_rect.top, 
	camara_rect.right - camara_rect.left, 600);
	Box b2(p_qnode->getX1(), p_qnode->getY1(), 
	p_qnode->getX2() - p_qnode->getX1(), p_qnode->getY2() - p_qnode->getY1());
	if (Collision::AABBCheck(b1, b2))
	{
	is_clip = true;
	}*/
	/*box1, box2;
	!(b1.x + b1.w < b2.x || b1.x > b2.x + b2.w || b1.y + b1.h < b2.y || b1.y > b2.y + b2.h);*/


	if (!(camara_rect.left + camara_rect.right < p_qnode->getX1() || camara_rect.left > p_qnode->getX2() || camara_rect.top + camara_rect.bottom < p_qnode->getY1() || camara_rect.top > p_qnode->getY2()))
	{
		is_clip = true;
	}
	else
	{
		is_clip = false;
	}

	if (is_clip == true)
	{
		//lay danh sach doi tuong cua qnode
		Object *obj;

		list<Object*>::const_iterator it;
		for (it = p_qnode->obj_list.begin(); it != p_qnode->obj_list.end(); it++)
		{
			obj = *it;

			if (!(obj->getObjState() == 0)) //trang thai REMOVE
			{


				//////////////////////////////////////////////////////////////////////////
				//kiem tra xem obj da co trong p_obj_list hay chua?
				//neu co thi k them vao
				bool is_drawed = false;
				Object *obj_drawed;

				list<Object*>* obj_drawed_list = p_obj_list;
				list<Object*>::iterator i_obj_drawed = obj_drawed_list->begin();
				while (i_obj_drawed != obj_drawed_list->end() && is_drawed == false)
				{
					obj_drawed = *i_obj_drawed;
					if (obj->getIDObj() == obj_drawed->getIDObj())
					{
						is_drawed = true;

					}
					++i_obj_drawed;
				}
				//////////////////////////////////////////////////////////////////////////
				if (is_drawed == false)
				{
					//kiem tra obj nam khong qua xa camera: khac phuc tinh trang bi giat
					if (obj->getPosX() > camara_rect.left - 30 && obj->getPosX() < camara_rect.left + 800 + 30)
					{
						p_obj_list->push_back(obj);
					}

					//p_obj_list->push_back(obj); //hoi bi giat
				}
				//p_obj_list->push_back(obj);
			}
		}

		//list<Object*> const obj_list = p_qnode->getObjList();	//khai bao const trong truong hop bi loi iterator
		//list<Object*>::const_iterator it = obj_list.begin();
		//while (it != obj_list.end())
		//{
		//	obj = *it;
		//	//////////////////////////////////////////////////////////////////////////
		//	//kiem tra xem obj da co trong p_obj_list hay chua?
		//	//neu co thi k them vao
		//	bool is_drawed = false;
		//	Object *obj_drawed;

		//	list<Object*>* obj_drawed_list = p_obj_list;
		//	list<Object*>::iterator i_obj_drawed = obj_drawed_list->begin();
		//	while (i_obj_drawed != obj_drawed_list->end() && is_drawed == false)
		//	{
		//		obj_drawed = *i_obj_drawed;
		//		if (obj->getIDObj() == obj_drawed->getIDObj())
		//		{
		//			is_drawed = true;
		//			
		//		}
		//		++i_obj_drawed;
		//	}
		//	//////////////////////////////////////////////////////////////////////////
		//	if (is_drawed == false)
		//	{
		//		p_obj_list->push_back(obj);
		//	}
		//	
		//	++it;
		//}
	}
}

void QuadTree::getObjFromCamara(RECT camara_rect, list<Object*>* p_obj_list)
{
	getObjFromCamara(this->root, camara_rect, p_obj_list);

}

void QuadTree::getObjFromCamara(QNode *p_qnode, RECT camara_rect, list<Object*>* p_obj_list)
{
	//if (p_qnode->getLevel() >= max_level)
	if (p_qnode->getLeftTop() == NULL || 
		p_qnode->getRightTop() == NULL || 
		p_qnode->getLeftBottom() == NULL ||
		p_qnode->getRightBottom() == NULL)
	{
		//node con
		clip(camara_rect, p_qnode, p_obj_list);
		//return ;
	}
	else
	{
		getObjFromCamara(p_qnode->getLeftTop(), camara_rect, p_obj_list);
		getObjFromCamara(p_qnode->getRightTop(), camara_rect, p_obj_list);
		getObjFromCamara(p_qnode->getLeftBottom(), camara_rect, p_obj_list);
		getObjFromCamara(p_qnode->getRightBottom(), camara_rect, p_obj_list);
	}



}

void QuadTree::getObjList(list<Object*>* p_obj_list)
{
	getObjList(this->root, p_obj_list);
}

void QuadTree::getObjList(QNode *p_qnode, list<Object*>* p_obj_list)
{
	if (p_qnode->getLeftTop() == NULL || 
		p_qnode->getRightTop() == NULL || 
		p_qnode->getLeftBottom() == NULL ||
		p_qnode->getRightBottom() == NULL)
	{
		//node con
		//clip(camara_rect, p_qnode, p_obj_list);
		list<Object*> temp_list;
		temp_list = p_qnode->getObjList();
		Object *obj;
		list<Object*>::const_iterator iList;// = p_qnode->getObjList().begin();
		for (iList = temp_list.begin(); iList != temp_list.end(); iList++)
		{
			obj = *iList;
			p_obj_list->push_back(obj);
			//iList = temp_list.erase(iList);
		}
		/*while (iList != p_qnode->getObjList().end())
		{
			obj = *iList;
			p_obj_list->push_back(obj);
			iList++;
		}*/
		
		//return ;
	}
	else
	{
		getObjList(p_qnode->getLeftTop(), p_obj_list);
		getObjList(p_qnode->getRightTop(), p_obj_list);
		getObjList(p_qnode->getLeftBottom(), p_obj_list);
		getObjList(p_qnode->getRightBottom(), p_obj_list);
	}
}